using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Coding4Fun.Phone.Controls;
using Lasalara.Model;
using Microsoft.Phone.Shell;

namespace Lasalara.ViewModel
{
    public class GlobalViewModel
    {

        /// <summary>
        /// Displays the progress bar.
        /// </summary>
        /// <param name="text">Progress bar text</param>
        /// <param name="bar">Progress bar to display</param>
        public static void ShowProgressBar(ProgressIndicator bar, string text)
        {
            bar.IsIndeterminate = true;
            bar.Text = text;
            bar.IsVisible = true;
        }

        /// <summary>
        /// Hides the indeterminate progress bar.
        /// </summary>
        public static void HideProgressBar(ProgressIndicator bar)
        {
            bar.IsIndeterminate = false;
            bar.Text = "";
            bar.IsVisible = false;
        }

        /// <summary>
        /// Removes progress from live tile when user logs out.
        /// </summary>
        public static void RemoveLiveTileProgress()
        {
            var tile = ShellTile.ActiveTiles.First();
            var newBackContent = "Are" + Environment.NewLine;
            newBackContent += "you" + Environment.NewLine;
            newBackContent += "done?" + Environment.NewLine;

            var newTileData = new StandardTileData
                              {
                                  Count = 0,
                                  BackTitle = "log in",
                                  BackContent = newBackContent
                              };
            tile.Update(newTileData);
        }

        /// <summary>
        /// Update Live Tile progress in background thread.
        /// </summary>
        public static void UpdateLiveTileProgress(User currentUser)
        {
            // Find tile
            var tileToFind = ShellTile.ActiveTiles.First();
            var newTileData = new StandardTileData();
            var bw = new BackgroundWorker();
            bw.DoWork += (sender, args) =>
            {
                double totalQuestionsDownloaded =
                    currentUser.DownloadedUserBooks.SelectMany(
                        book => book.Chapters.Where(x => x.IsDownloaded)).Sum(
                            chapter => chapter.QuestionCount);
                double totalQuestionsAnswered =
                    currentUser.DownloadedUserBooks.SelectMany(
                        book => book.Chapters.Where(x => x.IsDownloaded)).Sum(
                            chapter => chapter.AnsweredCount);
                var val = 0.0;
                if (!totalQuestionsAnswered.Equals(0))
                {
                    val = totalQuestionsAnswered / totalQuestionsDownloaded * 100;
                }
                if (val > 100)
                {
                    val = 100;
                }
                // newBackContent needs to be changed eventually
                var newBackContent = AppResources.Questions + ": " + totalQuestionsDownloaded + Environment.NewLine;
                newBackContent += AppResources.Answered + ": " + totalQuestionsAnswered + Environment.NewLine;
                var progress = (int)val + "%";
                if (val > 0 && val < 1)
                {
                    progress = "<1%";
                }

                if (val >= 100) val = 0;
                newTileData = new StandardTileData
                {
                    Title = "",
                    BackgroundImage = new Uri("ApplicationIcon.png", UriKind.Relative),
                    Count = (int)val,
                    BackTitle = progress,
                    BackBackgroundImage = new Uri("Application.png", UriKind.Relative),
                    BackContent = newBackContent
                };

            };
            bw.RunWorkerAsync();
            bw.RunWorkerCompleted += (sender, args) => tileToFind.Update(newTileData);
            
        }

        /// <summary>
        /// Shuffles given list
        /// </summary>
        /// <param name="list">List to shuffle</param>
        public static List<T> Randomize<T>(IEnumerable<T> list)
        {
            var rnd = new Random();
            return list.OrderBy((item) => rnd.Next()).ToList();
        }

        /// <summary>
        /// Randomizes the displayed logo and fades it in when it has loaded.
        /// </summary>
        public static void SetLogo(ImageBrush logo, Rectangle rectangle)
        {
            var link1 = new Uri("http://lasalara.googlecode.com/svn/trunk/Lasalara/Images/nike-ibelieve.png", UriKind.Absolute);
            var link2 = new Uri("http://lasalara.googlecode.com/svn/trunk/Lasalara/Images/nike-inredifining.png", UriKind.Absolute);
            var link3 = new Uri("http://lasalara.googlecode.com/svn/trunk/Lasalara/Images/nike-myimpossible.png", UriKind.Absolute);

            var sb = new Storyboard();
            var fadeInAnimation = new DoubleAnimation
                                      {From = 0, To = 1, Duration = new Duration(TimeSpan.FromSeconds(1.0))};

            Storyboard.SetTarget(fadeInAnimation, rectangle);
            Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath("Opacity"));

            sb.Children.Add(fadeInAnimation);

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                rectangle.Opacity = 0;
                if (rectangle.Name.Equals("booksLogoRectangle"))
                {
                    logo.ImageSource = new BitmapImage(link1);
                }
                if (rectangle.Name.Equals("chaptersLogoRectangle"))
                {
                    logo.ImageSource = new BitmapImage(link2);
                }
                if (rectangle.Name.Equals("logoStudyViewRectangle") || rectangle.Name.Equals("logoPageViewRectangle"))
                {
                    logo.ImageSource = new BitmapImage(link3);
                }
                
                logo.ImageOpened += (sender, args) => sb.Begin();
            }

        }
        /// <summary>
        /// Hides or shows the cancel web request button
        /// </summary>
        public static void ShowCancelButton(bool isVisible, UIElement grid)
        {
            var fadeStoryBoard = new Storyboard();
            var fadeAnimation = new DoubleAnimation()
            {
                Duration = new Duration(TimeSpan.FromMilliseconds(500))
            };
            fadeStoryBoard.Children.Add(fadeAnimation);

            Storyboard.SetTarget(fadeAnimation, grid);
            Storyboard.SetTargetProperty(fadeAnimation, new PropertyPath("Opacity"));

            if (isVisible)
            {
                grid.Visibility = Visibility.Visible;
                fadeAnimation.From = 0;
                fadeAnimation.To = 1;
                fadeStoryBoard.Begin();
            }
            else
            {
                fadeAnimation.From = 1;
                fadeAnimation.To = 0;
                fadeStoryBoard.Begin();
                fadeStoryBoard.Completed += (sender, args) => grid.Visibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// Shows toast notification
        /// </summary>
        /// <param name="title">message title</param>
        /// <param name="message">message content</param>
        public static void ShowToast(string title, string message)
        {
            var toast = new ToastPrompt
                            {
                                Title = title,
                                Message = message,
                                TextOrientation = Orientation.Vertical,
                                TextWrapping = TextWrapping.Wrap
                            };
            toast.Show();
        }

        /// <summary>
        /// Encrypts users password
        /// </summary>
        /// <param name="data">User's password</param>
        public static byte[] EncryptData(string data)
        {
            var dataBytes = Encoding.UTF8.GetBytes(data);
            var encryptedPasswordData = ProtectedData.Protect(dataBytes, null);
            return encryptedPasswordData;
        }

        /// <summary>
        /// Save data to localstorage
        /// </summary>
        /// <param name="key">The key to save</param>
        /// <param name="value">The value of the key</param>
        public static void SetAppSetting(string key, object value)
        {
            var appSettings = IsolatedStorageSettings.ApplicationSettings;
            try
            {
                if (appSettings.Contains(key))
                {
                    appSettings[key] = value;
                }
                else
                {
                    appSettings.Add(key, value);
                }
            }
            catch (ArgumentException ex)
            {
                MessageBox.Show(AppResources.ErrorSavingData + ":" + ex, AppResources.Error, MessageBoxButton.OK);
            }
        }

        /// <summary>
        /// Fetch data from localstorage. Returns null if setting not found.
        /// </summary>
        /// <param name="key">The key of the value to fetch</param>
        public static object GetAppSettings(string key)
        {
            var appSettings = IsolatedStorageSettings.ApplicationSettings;

            if (appSettings.Contains(key))
            {
                return appSettings[key];
            }
            return null;
        }

        /// <summary>
        /// Validate if the email is syntactically correct
        /// </summary>
        /// <param name="email">The email to validate</param>
        public static bool ValidateEmail(string email)
        {
            const string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                                    @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                                    @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            var re = new Regex(strRegex);
            return re.IsMatch(email);
        }

        /// <summary>
        /// Gets the current user from IsolatedStorageSettings. Returns null if no user is found.
        /// </summary>
        public static User GetCurrentUser()
        {
            var userName = GetAppSettings("currentUser");
            if (userName != null)
            {
                var currentUser = GetAppSettings(userName.ToString());
                if (currentUser != null)
                {
                    return currentUser as User;
                }
            }
            return null;
        }

        /// <summary>
        /// Saves current user to storage
        /// </summary>
        public static void SaveUser(User user)
        {
            SetAppSetting(user.Email, user);
        }
    }
}